package cn.easyutil.util.platform.jiguang;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.easyutil.util.javaUtil.HttpUtil;
import cn.easyutil.util.javaUtil.JsonUtil;
import cn.easyutil.util.javaUtil.StringUtil;
import cn.easyutil.util.platform.jiguang.bean.JiguangIMUser;
import cn.easyutil.util.platform.jiguang.bean.JiguangQueryResult;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * 极光im聊天
 * @author spc
 *
 */
public class JiguangIMUtil {

	private String appkey;
	private String masterSecret;
	//极光header权限鉴定的key
	private String authKey = "Authorization";
	//极光请求父路径
	private String baseUrl="https://api.im.jpush.cn";
	/**
	 * 极光参数
	 * @param appkey
	 * @param masterSecret
	 */
	public JiguangIMUtil(String appkey,String masterSecret){
		this.appkey = appkey;
		this.masterSecret = masterSecret;
	}
	
	public static JiguangIMUtil build(String appkey,String masterSecret){
		return new JiguangIMUtil(appkey, masterSecret);
	}

	public String getAppkey() {
		return appkey;
	}

	public void setAppkey(String appkey) {
		this.appkey = appkey;
	}

	public String getMasterSecret() {
		return masterSecret;
	}

	public void setMasterSecret(String masterSecret) {
		this.masterSecret = masterSecret;
	}
	
	/**
	 * 注册用户到极光IM
	 * @param username	用户名(平台唯一)
	 * @param password	用户密码，用户IM登陆
	 */
	public void registUser(String username,String password){
		registUser(username, password, null);
	}
	
	/**
	 * 注册用户到极光IM
	 * @param username	用户名(平台唯一)
	 * @param password	用户密码，用户IM登陆
	 * @param user	用户的其他信息
	 */
	public void registUser(String username, String password, JiguangIMUser user){
		if(StringUtil.isEmpty(username) || username.startsWith("0")){
			throw new RuntimeException("用户名不能为空并且不能以0开头");
		}
		if(StringUtil.isEmpty(password)){
			throw new RuntimeException("用户密码不能为空");
		}
		if(user == null){
			user = new JiguangIMUser();
		}
		HttpUtil util = getHttpUtil("/v1/users/");
		util.setRequestMethod("POST");
		Map<String, String> param = new HashMap<String, String>();
		param.put("username", username);
		param.put("password", password);
		param.putAll(parseUser(user));
		List<Map<String, String>> list = new ArrayList<Map<String,String>>();
		list.add(param);
		util.setJsonRequestParam(list);
		util.doUrl();
	}
	
	/**
	 * 注册管理员到极光IM
	 * @param username	用户名(平台唯一)
	 * @param password	用户密码，用户IM登陆
	 */
	public void registAdmin(String username,String password){
		registAdmin(username, password, null);
	}
	
	/**
	 * 注册管理员到极光IM
	 * @param username	用户名(平台唯一)
	 * @param password	用户密码，用户IM登陆
	 * @param user	用户的其他信息
	 */
	public void registAdmin(String username,String password,JiguangIMUser user){
		if(StringUtil.isEmpty(username) || username.startsWith("0")){
			throw new RuntimeException("用户名不能为空并且不能以0开头");
		}
		if(StringUtil.isEmpty(password)){
			throw new RuntimeException("用户密码不能为空");
		}
		if(user == null){
			user = new JiguangIMUser();
		}
		HttpUtil util = getHttpUtil("/v1/admins/");
		util.setRequestMethod("POST");
		Map<String, String> param = new HashMap<String, String>();
		param.put("username", username);
		param.put("password", password);
		param.putAll(parseUser(user));
		util.setJsonRequestParam(param);
		util.doUrl();
	}
	
	/**
	 * 分页获取管理员列表
	 * @param currentPage	当前页
	 * @param showCount	每页显示条目数
	 * @return 
	 */
	public JiguangQueryResult getAdminsList(int currentPage, int showCount){
		HttpUtil util = getHttpUtil("/v1/admins?start="+(currentPage*showCount)+"&count="+showCount);
		util.setRequestMethod("GET");
		String result = util.doUrl();
		return JsonUtil.jsonToBean(result, JiguangQueryResult.class);
	}
	
	/**
	 * 获取用户详情
	 * @param username
	 * @return 
	 */
	public JiguangIMUser getUserInfo(String username){
		if(StringUtil.isEmpty(username) || username.startsWith("0")){
			throw new RuntimeException("用户名不能为空并且不能以0开头");
		}
		HttpUtil util = getHttpUtil("/v1/users/"+username);
		util.setRequestMethod("GET");
		String result = util.doUrl();
		JiguangIMUser user = JsonUtil.jsonToBean(result, JiguangIMUser.class);
		Map<String, Object> map = JsonUtil.jsonToMap(result);
		if(map.get("avatar") != null){
			user.setHeaderImg(map.get("avatar").toString());
		}
		if(map.get("gender") != null){
			Integer gender = Integer.valueOf(map.get("gender").toString());
			gender = gender==1?1:gender==2?0:-1;
			user.setSex(gender);
		}
		return user;
	}
	
	/**
	 * 更新用户信息
	 * @param username	用户名
	 * @param user
	 */
	public void updateUserInfo(String username,JiguangIMUser user){
		if(StringUtil.isEmpty(username) || username.startsWith("0")){
			throw new RuntimeException("用户名不能为空并且不能以0开头");
		}
		HttpUtil util = getHttpUtil("/v1/users/"+username);
		util.setRequestMethod("PUT");
		util.setJsonRequestParam(parseUser(user));
		util.doUrl();
	}
	
	/**
	 * 查询用户是否在线
	 * @param username
	 * @return true:在线
	 */
	public boolean getUserOnlineStatus(String username){
		if(StringUtil.isEmpty(username)){
			throw new RuntimeException("用户名不能为空");
		}
		HttpUtil util = getHttpUtil("/v1/users/"+username+"/userstat");
		try {
			String result = util.setRequestMethod("GET").doUrl();
			Map<String, Object> map = JsonUtil.jsonToMap(result);
			return Boolean.valueOf(map.get("online").toString());
		} catch (Exception e) {
			return false;
		}
		
	}
	
	/**
	 * 批量获取用户在线状态
	 * @param usernames
	 * @return
	 */
	public List<UserOnlineStatus> getUserOnlineStatus(Collection<String> usernames){
		if(usernames==null || usernames.size()==0){
			throw new RuntimeException("用户名不能为空");
		}
		HttpUtil util = getHttpUtil("/v2/users/statuser");
		util.setRequestMethod("POST");
		util.setJsonRequestParam(usernames);
		String result = util.doUrl();
		JSONArray array = JSONArray.parseArray(result);
		List<UserOnlineStatus> list = new ArrayList<JiguangIMUtil.UserOnlineStatus>();
		for (Object object : array) {
			if(object instanceof JSONObject){
				JSONObject obj = (JSONObject) object;
				JSONArray devices = obj.getJSONArray("devices");
				UserOnlineStatus status = new UserOnlineStatus();
				if(devices!=null && devices.size()>0){
					@SuppressWarnings("rawtypes")
					Map dev = devices.getObject(0, Map.class);
					if(dev!=null && dev.get("online")!=null){
						status.setOnline(Boolean.valueOf(dev.get("online").toString()));
					}else{
						status.setOnline(false);
					}
				}
				if(obj.getString("username") != null){
					status.setUsername(obj.getString("username"));
				}
				list.add(status);
			}
		}
		return list;
	}
	
	/**
	 * 更新用户密码
	 * @param username
	 * @param password
	 */
	public void updateUserPassword(String username,String password){
		if(StringUtil.isEmpty(username)){
			throw new RuntimeException("用户名不能为空");
		}
		if(StringUtil.isEmpty(password)){
			throw new RuntimeException("密码不能为空");
		}
		HttpUtil util = getHttpUtil("/v1/users/"+username+"/password");
		Map<String, String> param = new HashMap<String, String>();
		param.put("new_password", password);
		util.setJsonRequestParam(param);
		util.setRequestMethod("PUT");
		try {
			util.doUrl();
		} catch (Exception e) {}
	}
	
	/**
	 * 删除用户
	 * @param username
	 */
	public void deleteUsers(String...usernames){
		if(usernames.length == 0){
			throw new RuntimeException("用户名不能为空");
		}
		HttpUtil util = getHttpUtil("/v1/users/");
		util.setRequestMethod("DELETE");
		util.setJsonRequestParam(Arrays.asList(usernames));
		util.doUrl();
	}
	
	/**
	 * 设置黑名单
	 * @param username	目标用户
	 * @param blackUsers	目标用户的黑名单
	 */
	public void setBlackList(String username,String...blackUsers){
		if(StringUtil.isEmpty(username) || blackUsers.length==0){
			throw new RuntimeException("用户名不能为空");
		}
		HttpUtil util = getHttpUtil("/v1/users/"+username+"/blacklist");
		util.setRequestMethod("PUT");
		util.setJsonRequestParam(Arrays.asList(blackUsers));
		util.doUrl();
	}
	
	/**
	 * 移除黑名单
	 * @param username	目标用户
	 * @param blackUsers	目标用户的黑名单
	 */
	public void deleteBlackList(String username,String...blackUsers){
		if(StringUtil.isEmpty(username) || blackUsers.length==0){
			throw new RuntimeException("用户名不能为空");
		}
		HttpUtil util = getHttpUtil("/v1/users/"+username+"/blacklist");
		util.setRequestMethod("DELETE");
		util.setJsonRequestParam(Arrays.asList(blackUsers));
		util.doUrl();
	}
	
	/**
	 * 获取用户的黑名单列表
	 * @param username
	 * @return 
	 */
	public List<JiguangIMUser> getBlackList(String username){
		if(StringUtil.isEmpty(username)){
			throw new RuntimeException("用户名不能为空");
		}
		HttpUtil util = getHttpUtil("/v1/users/"+username+"/blacklist");
		util.setRequestMethod("GET");
		String result = util.doUrl();
		return JsonUtil.jsonToList(result, JiguangIMUser.class);
		
	}
	
	/**
	 * 获取用户列表
	 * @param currentPage	当前页
	 * @param showCount	每页显示条目数
	 * @return
	 */
	public JiguangQueryResult getUserList(int currentPage, int showCount){
		HttpUtil util = getHttpUtil("/v1/users/?start="+(currentPage*showCount)+"&count="+showCount);
		util.setRequestMethod("GET");
		return JsonUtil.jsonToBean(util.doUrl(), JiguangQueryResult.class);
	}
	
	/**
	 * 设置单聊免打扰
	 * @param type	0-全局取消免打扰  1-全局设为免打扰  2-设置单聊用户免打扰  3-取消单聊用户免打扰  4-设置群组聊天免打扰  5-取消群组聊天免打扰
	 * @param username	目标用户
	 * @param singleUsers	免打扰用户
	 */
	public void setUserNodisturb(int type,String username,String...singleUsers){
		if(StringUtil.isEmpty(username)){
			throw new RuntimeException("用户名不能为空");
		}
		HttpUtil util = getHttpUtil("/v1/users/"+username+"/nodisturb");
		util.setRequestMethod("POST");
		Map<String, Object> param = new HashMap<String, Object>();
		//全局设置
		if(type == 0 || type == 1) {
			param.put("global", type);
			util.setJsonRequestParam(param);
			util.doUrl();
			return;
		}
		//单聊免打扰
		if(type == 2){
			Map<String, Object> single = new HashMap<String, Object>();
			single.put("add", Arrays.asList(singleUsers));
			param.put("single", single);
			util.setJsonRequestParam(param);
			util.doUrl();
			return;
		}
		//取消单聊免打扰
		if(type == 3){
			Map<String, Object> single = new HashMap<String, Object>();
			single.put("remove", Arrays.asList(singleUsers));
			param.put("single", single);
			util.setJsonRequestParam(param);
			util.doUrl();
			return;
		}
		//群聊免打扰
		if(type == 4){
			Map<String, Object> group = new HashMap<String, Object>();
			group.put("add", Arrays.asList(singleUsers));
			param.put("group", group);
			util.setJsonRequestParam(param);
			util.doUrl();
			return;
		}
		//取消群聊免打扰
		if(type == 5){
			Map<String, Object> group = new HashMap<String, Object>();
			group.put("remove", Arrays.asList(singleUsers));
			param.put("group", group);
			util.setJsonRequestParam(param);
			util.doUrl();
			return;
		}
	}
	
	/**
	 * 发送消息给IM用户
	 * @param type	0-个人到个人  1-个人到群组  2-个人到聊天室  3-管理员到个人  4-管理员到群组  5-管理员到聊天室
	 * @param fromUsername	发送者账号
	 * @param toUsername	接收者账号
	 * @param text	消息内容
	 * @param img	图片地址
	 * @return 
	 */
	public String sendMsg(int type,String fromUsername,String toUsername,String text,String img){
		if(StringUtil.isEmpty(fromUsername) || StringUtil.isEmpty(toUsername)){
			throw new RuntimeException("用户名不能为空");
		}
		if(StringUtil.isEmpty(text) && StringUtil.isEmpty(img)){
			throw new RuntimeException("消息内容不能为空");
		}
		HttpUtil util = getHttpUtil("/v1/messages");
		util.setRequestMethod("POST");
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("version", 1);
		param.put("target_id", toUsername);
		param.put("from_id", fromUsername);
		Map<String, Object> msgBody = new HashMap<String, Object>();
		if(img != null){
			param.put("msg_type", "image");
			msgBody.put("media_id", img);
			msgBody.put("media_crc32", "");//文件魔数
			msgBody.put("width", "");//图片宽度
			msgBody.put("height", "");//图片高度
			msgBody.put("fsize", "");//图片大小
			msgBody.put("format", "JPG");//文件类型
		}else{
			param.put("msg_type", "text");
			msgBody.put("text", text);
		}
		param.put("msg_body", msgBody);
		switch (type) {
			//个人到个人
			case 0:{
				param.put("from_type", "user");
				param.put("target_type", "single");
				break;
			}
			//个人到群组
			case 1:{
				param.put("from_type", "user");
				param.put("target_type", "group");
				break;
			}
			//个人到聊天室
			case 2:{
				param.put("from_type", "user");
				param.put("target_type", "chatroom");
				break;
			}
			//管理员到个人
			case 3:{
				param.put("from_type", "admin");
				param.put("target_type", "single");
				break;
			}
			//管理员到群组
			case 4:{
				param.put("from_type", "admin");
				param.put("target_type", "group");
				break;
			}
			//管理员到聊天室
			case 5:{
				param.put("from_type", "admin");
				param.put("target_type", "chatroom");
				break;
			}
			default:{
				throw new RuntimeException("类型错误");
			}
		}
		String result = util.setJsonRequestParam(param).doUrl();
		return JsonUtil.jsonToMap(result).get("msg_id").toString();
	}
	
	/**
	 * 撤回消息	
	 * @param username	发送此消息的用户
	 * @param msgId	消息id
	 */
	public void cancelMsg(String username,String msgId){
		if(StringUtil.isEmpty(username)){
			throw new RuntimeException("用户名不能为空");
		}
		if(StringUtil.isEmpty(msgId)){
			throw new RuntimeException("消息id不能为空");
		}
		HttpUtil util = getHttpUtil("/v1/messages/"+username+"/"+msgId+"/retract");
		util.setRequestMethod("POST");
		try {
			util.doUrl();
		} catch (Exception e) {}
	}
	
	/**
	 * 添加好友
	 * @param username	目标用户
	 * @param friendsUsers	目标用户的好友
	 */
	public void setFriends(String username,String...friendsUsers){
		if(StringUtil.isEmpty(username) || friendsUsers.length==0){
			throw new RuntimeException("用户名不能为空");
		}
		HttpUtil util = getHttpUtil("/v1/users/"+username+"/friends");
		util.setRequestMethod("POST");
		util.setJsonRequestParam(Arrays.asList(friendsUsers));
		util.doUrl();
	}
	
	/**
	 * 删除好友
	 * @param username	目标用户
	 * @param friendsUsers	目标用户的好友
	 */
	public void deleteFriends(String username,String...friendsUsers){
		if(StringUtil.isEmpty(username) || friendsUsers.length==0){
			throw new RuntimeException("用户名不能为空");
		}
		HttpUtil util = getHttpUtil("/v1/users/"+username+"/friends");
		util.setRequestMethod("DELETE");
		util.setJsonRequestParam(Arrays.asList(friendsUsers));
		util.doUrl();
	}
	
	/**
	 * 给好友设置别名
	 * @param username
	 * @param friendUsername
	 * @param aliasName
	 */
	public void setFriendsAlias(String username,String friendUsername,String aliasName){
		if(StringUtil.isEmpty(username) || StringUtil.isEmpty(friendUsername) || StringUtil.isEmpty(aliasName)){
			throw new RuntimeException("用户名不能为空");
		}
		HttpUtil util = getHttpUtil("/v1/users/"+username+"/friends");
		Map<String, String> param = new HashMap<String, String>();
		param.put("note_name", aliasName);
		param.put("username", friendUsername);
		List<Map<String, String>> list = new ArrayList<Map<String,String>>();
		list.add(param);
		util.setJsonRequestParam(list);
		util.setRequestMethod("PUT");
		try {
			util.doUrl();
		} catch (Exception e) {
			throw new RuntimeException("先成为好友才能修改备注");
		}
	}
	
	/**
	 * 获取好友列表
	 * @param username
	 * @return 
	 */
	public List<JiguangIMUser> getFriendsList(String username){
		if(StringUtil.isEmpty(username)){
			throw new RuntimeException("用户名不能为空");
		}
		HttpUtil util = getHttpUtil("/v1/users/"+username+"/friends");
		String result = util.setRequestMethod("GET").doUrl();
		return JsonUtil.jsonToList(result, JiguangIMUser.class);
	}
	
	public static void main(String[] args) {
		JiguangIMUtil push = JiguangIMUtil.build("49470b0d6ac0f900bf32352d", "7cc220ed09985564507605ef");
		push.updateUserPassword("6727", "e10adc3949ba59abbe56e057f20f883e");
	}
	
	
	private Map<String, String> parseUser(JiguangIMUser user){
		Map<String, String> param = new HashMap<String, String>();
		if(user == null){
			return param;
		}
		if(!StringUtil.isEmpty(user.getNickname())){
			param.put("nickname", user.getNickname());
		}
		if(!StringUtil.isEmpty(user.getAddress())){
			param.put("address", user.getAddress());
		}
		if(!StringUtil.isEmpty(user.getBirthday())){
			param.put("birthday", user.getBirthday());
		}
		if(!StringUtil.isEmpty(user.getHeaderImg())){
			param.put("avatar", user.getHeaderImg());
		}
		if(!StringUtil.isEmpty(user.getSex())){
			Integer sex = user.getSex();
			sex = sex==0?2:sex==1?1:0;
			param.put("gender", sex.toString());
		}
		if(!StringUtil.isEmpty(user.getSignature())){
			param.put("signature", user.getSignature());
		}
		return param;
	}
	
	private HttpUtil getHttpUtil(String url){
		//http请求工具
		 HttpUtil util = new HttpUtil();
		util.setRequestUrl(baseUrl+url);
		util.setHeaders(authKey, "Basic "+StringUtil.base64Encode(this.appkey+":"+this.masterSecret));
		util.setHeaders("Content-Type", "application/json");
		return util;
	}
	
	
	class UserOnlineStatus implements Serializable{
		private static final long serialVersionUID = 1L;
		
		private String username;
		private boolean online;
		public String getUsername() {
			return username;
		}
		public void setUsername(String username) {
			this.username = username;
		}
		public boolean isOnline() {
			return online;
		}
		public void setOnline(boolean online) {
			this.online = online;
		}
		
		
	}
}
